<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js"><span id='check'>/**
</span> * @author Ezios
 * @class check
 * @extends jquery-1.8.3
 * @markdown
 * #校验插件
 * 版本 0.2.3 日期 2015-4-13
 * 校验条件列表详见Config options
 *
 * 示例：
 * 在需要校验的表单元素上加上校验条件data-check属性， 如data-check=&quot;max-len:10&quot;
 * 
 *     @example
 *     if($(&#39;form&#39;).check()){
 *         alert(&#39;校验通过&#39;);
 *     }
 *
 *     $(&#39;dom&#39;).check(&#39;setCheck&#39;, {
 *         check: &#39;*&#39;
 *     });
 */
<span id='check-cfg-data-check'>/**
</span> * @cfg data-check 校验条件
 *      &lt;p&gt;多个条件用 | 隔开&lt;/p&gt;
 * @cfg [data-check.must] 必填项
 * @cfg [data-check.n] 仅为数字
 * @cfg [data-check.mobile] 手机号
 * @cfg [data-check.max-len] 最大长度
 *
 *      data-check=&quot;max-len: 10&quot;
 * @cfg [data-check.max-char-len] 字符最大长度 区分汉字和英文
 *
 *      data-check=&quot;max-char-len: 10&quot;
 * @cfg [data-check.min-len] 最小长度
 *
 *      data-check=&quot;min-len: 10&quot;
 * @cfg [data-check.min-char-len] 字符最小长度 区分汉字和英文
 *
 *      data-check=&quot;min-char-len: 10&quot;
 * @cfg [data-check.fit] 校验指定name值的表单元素的值是否与校验元素相同，例如确认密码
 *
 *      data-check=&quot;fit: account&quot;
 * @cfg [data-check.scope] 数字区间限制
 * 
 *      data-check=&quot;scope: 1-10&quot;
 * @cfg [data-check.idcard] 身份证
 * 
 *      data-check=&quot;idcard&quot;
 * @cfg [data-check.url] url地址
 *
 *      data-check=&quot;url&quot;
 * @cfg [data-check.email] 电子邮箱
 *
 *      data-check=&quot;email&quot;
 * @cfg [data-check.ip] ip地址
 *
 *      data-check=&quot;ip&quot;
 * @cfg [data-check.custom] 自定义验证函数
 *
 *      在表单元素上定义函数名
 *      data-check=&quot;custom: functionName&quot;
 *      在window对象上添加新函数
 *      --$control 校验元素dom
 *      function functionName($control){
 *          //CODE
 *          return {
 *              //&#39;验证是否通过的标志&#39;
 *              flag: false,
 *              //&#39;验证失败时显示的信息&#39;
 *              message: &#39;验证失败&#39;
 *          };
 *      }
 *
 */
;!(function($) {
    var $me = {};
    var cls = {
        errorCls: &#39;error-input&#39;,
        selectCls: &#39;ui-selectbox&#39;
    };
    var checkMethods ={
        isEmpty: function(val){
            if($.trim(val).length === 0){
                return true;
            }else{
                return false;
            }
        },
        isNumeric: function(val){
            if(checkMethods.isEmpty(val)){
                return true;
            }
            if($.isNumeric(val)){
                return true;
            }else{
                return false;
            }
        },
        isMobile: function(val){
            if(checkMethods.isEmpty(val)){
                return true;
            }
            return !!val.match(/^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/);
        },
        isIdcard: function(val) { 
            var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ];    // 加权因子   
            var ValideCode = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ];            // 身份证验证位值.10代表X   
            function IdCardValidate(idCard) { 
                idCard = trim(idCard.replace(/ /g, &quot;&quot;));               //去掉字符串头尾空格                     
                if (idCard.length == 15) {   
                    return isValidityBrithBy15IdCard(idCard);       //进行15位身份证的验证    
                } else if (idCard.length == 18) {   
                    var a_idCard = idCard.split(&quot;&quot;);                // 得到身份证数组   
                    if(isValidityBrithBy18IdCard(idCard)&amp;&amp;isTrueValidateCodeBy18IdCard(a_idCard)){   //进行18位身份证的基本验证和第18位的验证
                        return true;   
                    }else {   
                        return false;   
                    }   
                } else {   
                    return false;   
                }   
            }   
<span id='check-method-isTrueValidateCodeBy18IdCard'>            /**
</span>             * @private
             * 判断身份证号码为18位时最后的验证位是否正确  
             */  
            function isTrueValidateCodeBy18IdCard(a_idCard) {   
                var sum = 0;                             // 声明加权求和变量   
                if (a_idCard[17].toLowerCase() == &#39;x&#39;) {   
                    a_idCard[17] = 10;                    // 将最后位为x的验证码替换为10方便后续操作   
                }   
                for ( var i = 0; i &lt; 17; i++) {   
                    sum += Wi[i] * a_idCard[i];            // 加权求和   
                }   
                valCodePosition = sum % 11;                // 得到验证码所位置   
                if (a_idCard[17] == ValideCode[valCodePosition]) {   
                    return true;   
                } else {   
                    return false;   
                }   
            }   
<span id='check-method-isValidityBrithBy18IdCard'>            /** @private
</span>              * 验证18位数身份证号码中的生日是否是有效生日  
              */  
            function isValidityBrithBy18IdCard(idCard18){   
                var year =  idCard18.substring(6,10);   
                var month = idCard18.substring(10,12);   
                var day = idCard18.substring(12,14);   
                var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));   
                // 这里用getFullYear()获取年份，避免千年虫问题   
                if(temp_date.getFullYear()!=parseFloat(year)   
                      ||temp_date.getMonth()!=parseFloat(month)-1   
                      ||temp_date.getDate()!=parseFloat(day)){   
                        return false;   
                }else{   
                    return true;   
                }   
            }   
<span id='check-method-isValidityBrithBy15IdCard'>            /**
</span>            * @private
            * 验证15位数身份证号码中的生日是否是有效生日  
            */  
            function isValidityBrithBy15IdCard(idCard15){   
              var year =  idCard15.substring(6,8);   
              var month = idCard15.substring(8,10);   
              var day = idCard15.substring(10,12);   
              var temp_date = new Date(year,parseFloat(month)-1,parseFloat(day));   
              // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法   
              if(temp_date.getYear()!=parseFloat(year)   
                      ||temp_date.getMonth()!=parseFloat(month)-1   
                      ||temp_date.getDate()!=parseFloat(day)){   
                        return false;   
                }else{   
                    return true;   
                }   
            }
            //去掉字符串头尾空格   
            function trim(str) {   
                return str.replace(/(^\s*)|(\s*$)/g, &quot;&quot;);   
            }  

            if(checkMethods.isEmpty(val)){
                return true;
            }

            return IdCardValidate(val);
        },
        /*计算字符串长度 中文为2*/
        countCharacters: function(str) {
            var totalCount = 0;
            for (var i = 0; i &lt; str.length; i++) {
                var c = str.charCodeAt(i);
                if ((c &gt;= 0x0001 &amp;&amp; c &lt;= 0x007e) || (0xff60 &lt;= c &amp;&amp; c &lt;= 0xff9f)) {
                    totalCount++;
                } else {
                    totalCount += 2;
                }
            }
            return totalCount;
        },
        isUrl: function(val){
            if(checkMethods.isEmpty(val)){
                return true;
            }
            var regExp = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;

            if(regExp.test(val)){
                return true;
            }else{
                return false;
            }
        },
        isEmail: function(val){
            if(checkMethods.isEmpty(val)){
                return true;
            }
            var regExp = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;

            if(regExp.test(val)){
                return true;
            }else{
                return false;
            }
        },
        isIp: function(val){
            if(checkMethods.isEmpty(val)){
                return true;
            }
            var regExp = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;

            if(regExp.test(val)){
                return true;
            }else{
                return false;
            }
        }
    };
    var methods = {
<span id='check-method-check'>        /**
</span>         * 校验方法
         * @return {Boolean} 校验通过返回true 失败返回false
         */
        check: function() {
            $me = $(this);
            //校验DOM集合
            var $dom = $me.find(&#39;[data-check]&#39;);
            //校验规则
            var checkRules = new Array();

            //清空之前的提示
            removeTip($dom);

            $me.data({
                isPass: true
            });

            for (var i = 0, domLen = $dom.length; i &lt; domLen; i++) {
                //包装DOM元素
                var $control = $($dom.get(i));

                //单个控件校验标志
                $control.data({
                    isPass: true
                });

                //忽略data-ignore为true的元素
                if ($control.data(&#39;ignore&#39;) === true) {
                    continue;
                }

                //获取校验规则数组
                checkRules = $.trim($control.data(&#39;check&#39;)).split(&#39;|&#39;);

                for (var j = 0, rulesLen = checkRules.length; j &lt; rulesLen; j++) {
                    //没有包含:的规则
                    if (checkRules[j].toString().indexOf(&#39;:&#39;) === -1) {
                        switch (checkRules[j]) {
                            //非空判断
                            case &#39;must&#39;:
                                if (checkMethods.isEmpty($control.val())) {
                                    showTip(false, $control, &#39;该项不能为空&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //仅为数字
                            case &#39;n&#39;:
                                if (!checkMethods.isNumeric($control.val())) {
                                    showTip(false, $control, &#39;请输入数字&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //手机号
                            case &#39;mobile&#39;:
                                if (!checkMethods.isMobile($control.val())) {
                                    showTip(false, $control, &#39;请输入正确的手机号码&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //身份证
                            case &#39;idcard&#39;:
                                if (!checkMethods.isIdcard($control.val())) {
                                    showTip(false, $control, &#39;请输入正确的身份证号码&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //URL
                            case &#39;url&#39;:
                                if(!checkMethods.isUrl($control.val())){
                                    showTip(false, $control, &#39;请输入正确的URL地址&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //电邮
                            case &#39;email&#39;:
                                if(!checkMethods.isEmail($control.val())){
                                    showTip(false, $control, &#39;请输入正确的电子邮箱&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                            //ip
                            case &#39;ip&#39;:
                                if(!checkMethods.isIp($control.val())){
                                    showTip(false, $control, &#39;请输入正确的ip地址&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                                break;
                        }
                    } else {
                        var limit = checkRules[j].split(&#39;:&#39;);

                        //去除空格
                        limit[1] = $.trim(limit[1]);

                        switch (limit[0]) {
                            //最大长度
                            case &#39;max-len&#39;:
                                if ($control.val().length &gt; parseInt(limit[1])) {
                                    showTip(false, $control, &#39;长度不能大于&#39; + parseInt(limit[1]) + &#39;个字符&#39;);
                                }
                                else{
                                    showTip(true, $control);
                                }
                                break;
                            //字符最大长度 区分汉字和英文
                            case &#39;max-char-len&#39;:
                                if (checkMethods.countCharacters($control.val()) &gt; parseInt(limit[1])) {
                                    showTip(false, $control, &#39;汉字不能大于&#39; + parseInt(limit[1] / 2) + &#39;个, 英文不能大于&#39; + parseInt(limit[1]) + &#39;个&#39;);
                                }
                                else{
                                    showTip(true, $control);
                                }
                                break;
                            //最小长度
                            case &#39;min-len&#39;:
                                if(checkMethods.isEmpty($control.val())){
                                    showTip(true, $control);
                                }else if ($control.val().length &lt; parseInt(limit[1])) {
                                    showTip(false, $control, &#39;长度不能小于&#39; + parseInt(limit[1]) + &#39;个字符&#39;);
                                }
                                else{
                                    showTip(true, $control);
                                }
                                break;
                            //字符最小长度 区分汉字和英文
                            case &#39;min-char-len&#39;:
                                if(checkMethods.isEmpty($control.val())){
                                    showTip(true, $control);
                                }else if (checkMethods.countCharacters($control.val()) &lt; parseInt(limit[1])) {
                                    showTip(false, $control, &#39;汉字不能小于&#39; + parseInt(limit[1] / 2) + &#39;个, 英文不能小于&#39; + parseInt(limit[1]) + &#39;个&#39;);
                                }
                                else{
                                    showTip(true, $control);
                                }
                                break;
                            //指定name的元素是否与校验元素值相同
                            case &#39;fit&#39;:
                                if ($($me).find(&#39;[name=&#39; + limit[1] + &#39;]&#39;).val() !== $control.val()) {
                                    showTip(false, $control, &#39;两次输入的内容不一致&#39;);
                                }
                                else{
                                    showTip(true, $control);
                                }
                                break;
                            //指定数字范围
                            case &#39;scope&#39;:
                                var scope = $.trim(limit[1]).split(&#39;-&#39;);
                                var min = Math.min(scope[0], scope[1]);
                                var max = Math.max(scope[0], scope[1]);

                                if(parseInt($control.val()) &lt; min || parseInt($control.val()) &gt; max){
                                    showTip(false, $control, &#39;请输入范围在&#39;+ min + &#39; - &#39; + max +&#39; 的数字&#39;);
                                }else{
                                    showTip(true, $control);
                                }
                            //自定义
                            case &#39;custom&#39;:
                                if(typeof window[limit[1]] === &#39;function&#39;){
                                    var obj = window[limit[1]]($control);

                                    if(!obj.flag){
                                        showTip(false, $control, obj.message);
                                    }else{
                                        showTip(true, $control);
                                    }
                                }
                                break;
                        }
                    }
                }

                //第一个控件获取焦点
                $dom.filter(&#39;.&#39; + cls.errorCls + &#39;:first&#39;).focus();
            };

            if ($me.data(&#39;isPass&#39;)) {
                return true;
            } else {
                return false;
            }
        },
<span id='check-method-setCheck'>        /**
</span>         * 为指定元素设置校验
         * @param {Object} checkArray 校验对象
         * 示例：
         * 
         *     $(this).check(&#39;setCheck&#39;, {
         *         check: &#39;*&#39;,
         *         title: &#39;账户名&#39;
         *     });
         */
        setCheck: function(checkArray) {
            if ($(this).length) {
                $(this).attr({
                    &#39;data-check&#39;: checkArray.check
                });
            }
        },
<span id='check-method-removeCheck'>        /**
</span>         * 移除校验
         * 示例：
         * 
         *     $(this).check(&#39;removeCheck&#39;);
         */
        removeCheck: function() {
            if (this) {
                $(this).removeAttr(&#39;data-check&#39;);
            }
        },
<span id='check-method-enabledCheck'>        /**
</span>         * 启用校验
         * 示例：
         * 
         *     $(this).check(&#39;enabledCheck&#39;);
         */
        enabledCheck: function() {
            if (this) {
                $(this).removeAttr(&#39;data-ignore&#39;);
            }
        },
<span id='check-method-disabledCheck'>        /**
</span>         * 禁用校验
         * 示例：
         * 
         *     $(this).check(&#39;disabledCheck&#39;);
         */
        disabledCheck: function() {
            if (this) {
                $(this).attr(&#39;data-ignore&#39;, &#39;true&#39;);
            }
        }
    };

    //修复IE6不支持indexOf函数
    if (!Array.indexOf) {
        Array.prototype.indexOf = function(obj) {
            for (var i = 0; i &lt; this.length; i++) {
                if (this[i] == obj) {
                    return i;
                }
            }
            return -1;
        }
    }
    //修复chrome自动填充无法获取值的问题
    if (navigator.userAgent.toLowerCase().indexOf(&quot;chrome&quot;) &gt;= 0) {
        $(window).load(function(){
            $(&#39;input:-webkit-autofill&#39;).each(function(){
                var text = $(this).val();
                var name = $(this).attr(&#39;name&#39;);
                $(this).after(this.outerHTML).remove();
                $(&#39;input[name=&#39; + name + &#39;]&#39;).val(text);
            });
        });
    }

<span id='check-method-showTip'>    /**
</span>     * @private
     * 显示提示信息
     * @param  {Dom} $control      校验元素
     * @param  {String} tipString 提示字符串
     */
    function showTip(flag, $control, tipString) {
        if(!flag){
            //校验未通过
            var html = &#39;&lt;span class=&quot;check-tip alert alert-danger&quot;&gt;&#39; + tipString + &#39;&lt;/span&gt;\n&#39;;

            //下拉框特殊处理
            if($control.is(&#39;select&#39;)){
                $control.parent().find(&#39;.&#39; + cls.selectCls).addClass(cls.errorCls);
                $control.addClass(cls.errorCls);
            }

            $me.data({
                isPass: false
            });
            $control.data({
                isPass: false
            });

            //显示提示
            $control.addClass(cls.errorCls);
            $control.parent().append(html);
        }

        if($control.data(&#39;isPass&#39;) == true){
            $control.parent().find(&#39;.&#39; + cls.errorCls).removeClass(cls.errorCls).end()
                .find(&#39;.form-tip&#39;).show();
        }else if($control.data(&#39;isPass&#39;) == false){
            $control.parent().find(&#39;.form-tip&#39;).hide();
        }
    }

<span id='check-method-removeTip'>    /**
</span>     * @private
     * 隐藏提示
     * @param  {[type]} $control 控件
     */
    function removeTip($control){
        $control.nextAll(&#39;.check-tip&#39;).remove()
            .end().nextAll(&#39;.form-tip&#39;).hide();
            
    }

    $.fn.check = function(method){
        if(methods[method]){
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if(typeof method === &#39;object&#39; || !method){
            return methods.check.apply(this, arguments);
        } else { //未找到参数指明的方法
            $.error(&#39;错误&quot;&#39; + method + &#39;&quot;方法未定义&#39;);
        }
    };
})(jQuery);</pre>
</body>
</html>
